package com.restfinder.restaurant.controller;

import java.util.Date;

import javax.validation.Valid;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

import com.restfinder.comment.model.Comment;
import com.restfinder.comment.service.CommentService;
import com.restfinder.common.component.JsonResponse;
import com.restfinder.common.component.JsonResponseFactory;
import com.restfinder.common.component.ValidationJsonResponse;
import com.restfinder.common.component.utils.JsonSpringUtils;
import com.restfinder.common.component.utils.MessageUtils;
import com.restfinder.rate.model.Rate;
import com.restfinder.rate.model.RateValue;
import com.restfinder.rate.service.RateService;
import com.restfinder.restaurant.model.Restaurant;
import com.restfinder.restaurant.service.RestaurantService;
import com.restfinder.user.component.RestaurantValidator;
import com.restfinder.user.component.UserValidator;
import com.restfinder.user.forms.RestaurantForm;
import com.restfinder.user.forms.UserForm;
import com.restfinder.user.model.User;
import com.restfinder.user.service.UserService;

@Controller(value="restaurantController")
@SessionAttributes("restaurantForm")
@Slf4j
public class RestaurantController {

	@Autowired
	private RestaurantService restaurantService;
	@Autowired
	private UserService userService;	
	@Autowired
	private CommentService commentService;
	@Autowired
	private RestaurantValidator restaurantValidator;
	@Autowired
	private RateService rateService;
	
	@InitBinder
	protected void initBinder(WebDataBinder binder){
		binder.setValidator(restaurantValidator);
	}
	
	@RequestMapping(value="/restaurant/{id}", method=RequestMethod.GET)
	public ModelAndView restaurantGet(@PathVariable long id){
		ModelMap modelMap = new ModelMap();
		boolean found = false;
		Restaurant restaurant = restaurantService.getById(id);
		if(restaurant!=null){
			RestaurantForm rf = new RestaurantForm();
			rf.setRestaurant(restaurant);			
			found = true;
			User loggedUser = userService.getLoggedUser();
			if (loggedUser!=null){
				Rate rate = rateService.getByUserAndRestaurant(loggedUser, restaurant);
				rf.setRate(rate);
			}
			modelMap.addAttribute("restaurantForm", rf);
			modelMap.addAttribute("average",rateService.getAverage(restaurant));
		}
		modelMap.addAttribute("found", found);
		return new ModelAndView("restaurant/restaurant", modelMap);	
	}
	
	@RequestMapping(value="/restaurant/comment", method=RequestMethod.POST)
	public @ResponseBody JsonResponse commentPost(@ModelAttribute("restaurantForm") @Valid RestaurantForm restaurantForm, BindingResult result){
		JsonResponse jsonResponse = JsonResponseFactory.createJsonResponse(result);
		if(!JsonSpringUtils.isSuccessResponse(jsonResponse)){
			jsonResponse.setResult(MessageUtils.createMessage("comment.error.title", "comment.error.content"));
			return jsonResponse;
		}
		else{
			try {
				Comment comment = restaurantForm.getComment();
				comment.setUser(userService.getLoggedUser());
				comment.setRestaurant(restaurantForm.getRestaurant());
				comment.setDate(new Date());
				commentService.save(comment);
				jsonResponse.setResult(MessageUtils.createMessage("comment.success.title", "comment.success.content"));
				return jsonResponse;
			} catch (Exception e) {
				e.printStackTrace();
				log.error("Error while saving comment",e);
				jsonResponse = new ValidationJsonResponse();
				jsonResponse.setStatus(JsonSpringUtils.JSON_STATUS_FAILURE);
				jsonResponse.setResult(MessageUtils.createMessage("comment.error.title", e));
				return jsonResponse;
			}
		}		
	}
	
	@RequestMapping(value="/restaurant/rate", method=RequestMethod.POST)
	public @ResponseBody JsonResponse rateRestaurant(
			@ModelAttribute("restaurantForm") @Valid RestaurantForm restaurantForm, BindingResult result,
			@RequestParam(value="price") String price,
			@RequestParam(value="food") String food,
			@RequestParam(value="service") String service,
			@RequestParam(value="climate") String climate){
		JsonResponse jsonResponse = JsonResponseFactory.createJsonResponse(result);
		if(!JsonSpringUtils.isSuccessResponse(jsonResponse)){
			jsonResponse.setResult(MessageUtils.createMessage("comment.error.title", "comment.error.content"));
			return jsonResponse;
		}
		else{
			try {
				Rate rate = rateService.getByUserAndRestaurant(userService.getLoggedUser(), restaurantForm.getRestaurant());
				if(rate==null){
					rate = new Rate();
					rate.setRestaurant(restaurantForm.getRestaurant());
					rate.setUser(userService.getLoggedUser());
				}
				rate.setFood(RateValue.getByString(food));
				rate.setClimate(RateValue.getByString(climate));
				rate.setService(RateValue.getByString(service));
				rate.setPrice(RateValue.getByString(price));
				rateService.saveOrUpdate(rate);
				jsonResponse.setResult(MessageUtils.createMessage("rate.success.title", "rate.success.content"));
				return jsonResponse;
			} catch (Exception e) {
				e.printStackTrace();
				log.error("Error while saving rate",e);
				jsonResponse = new ValidationJsonResponse();
				jsonResponse.setStatus(JsonSpringUtils.JSON_STATUS_FAILURE);
				jsonResponse.setResult(MessageUtils.createMessage("rate.error.title", e));
				return jsonResponse;
			}
		}	
	}
}
